/*
 * Copyright (C) 2007-2009 Alessandro Melandri
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package net.melandri.jtextfileparser.filters;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import net.melandri.jtextfileparser.beans.Row;
import net.melandri.jtextfileparser.dao.FileManager;


/**
 * Class for filtering a TextFile object. This is used to export TextFile content
 * 
 * @since 1.3.1
 * */
public class HTMLFileFilter extends OutputFileFilterImpl implements OutputFileFilter {

	private String pageTitle;
	private String contentBefore;
	private String contentAfter;
	private String cssFilePath;
	private boolean printFileRowNumbers = false;
	private boolean printRowNumbers = false;
	private boolean printHeaders = false;
	
	
	/**
	 * Keeps a table count to generate a unique id for every table
	 * */
	private int tableCount = 0;
	
	/**
	 * Keeps a sections count to generate a unique id for every section
	 * */
	private int sectionsCount = 0;
	
	
	/**
	 * Deafult css properties
	 * */
	private String[] styles  = {
								"body{font-family: arial, verdana, helvetica; font-size: 12px; padding: 10px; margin: 0;}",
								".jtable{width: 100%; border: 1px solid #e1e1e1;border-collapse:collapse}",
								"tr.even{background: #f1f1f1;}",
								"td.jtd{padding: 3px;border: 1px solid #e1e1e1;}",
								"td.num{width: 40px;text-align:right;font-weight: bold;background: #638c9c;color: #FFFFFF;}"
								};
	
	
	
	/**
	 * Contains the code to write data to the file system. This method is used when you invoke the <code>write</code> method in a TextFile object.
	 * 
	 * @param rows ArrayList of Row objects. 
	 * @since 1.4
	 * */
	public void write(ArrayList rows){
		
		ArrayList filteredRows = getRowsSubset(rows);
		
		FileManager htmlFile = new FileManager(this.fileName, this.filePath);
		htmlFile.createFile();
		
		try {
			htmlFile.writeLine( buildHeaders() );

			if (this.getContentBefore() != null && !this.getContentBefore().equals(""))
				htmlFile.writeLine( buildSection(this.getContentBefore()) );

			htmlFile.writeLine( buildTable(filteredRows) );

			if (getContentAfter() != null && !getContentAfter().equals(""))
				htmlFile.writeLine( buildSection(this.getContentAfter()) );
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			try {
				htmlFile.closeWrite();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		
		
	}
	
	
	/**
	 * Adds doctype, headers and body start tag
	 * <br><br>
	 * If the cssPath have not been defined, the default style sheet will be used
	 * */
	private String buildHeaders() {
		
		String headers = "";
		
		headers += "<!DOCTYPE html\n";
		headers += "     PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n";
		headers += "    \"DTD/xhtml1-transitional.dtd\">\n";

		headers += "<html>\n<head>\n";
		
		if (this.getPageTitle() != null)
			headers += "\t<title>" + this.getPageTitle() + "</title>\n";
		
		if (this.getCssFilePath() != null)
			headers += "\t<link rel=\"Stylesheet\" type=\"text/css\" href=\"" + this.getCssFilePath() + "\"/>\n";
		else{
			headers += "<style type=\"text/css\">\n";
			
			for (int i = 0; i < styles.length; i++) {
				headers += "\t" + styles[i] + "\n";
			}
			
			headers += "</style>";
		}
		
		headers += "</head>\n<body>";
			
		return headers;
	}
	
	
	/**
	 * Adds a text section into the page
	 * 
	 * @param text Text to be displayed into the page
	 * */
	public String buildSection(String text){
		
		String section = "";

		if (text.indexOf("\n") == -1){
			
			section += ("<div id=\"section" + sectionsCount + "\">\n\t<p>" + text + "</p>\n</div>");
			
		} else {
			
			String[] paragraphs = text.split("\n");
			
			section += "<div id=\"section" + sectionsCount + "\">" + "\n";
			
			for (int i = 0; i < paragraphs.length; i++) {
				section += "\t<p>" + paragraphs[i] + "</p>" + "\n";
			}
			
			section += "</div>";
			
		}
		
		sectionsCount++;
			
		return section;
	}
	
	
	/**
	 * Inserts a table into the page
	 * 
	 * @param rows 		Arraylist of Rows objects
	 * */
	public String buildTable(ArrayList rows){
		
		String table = "";
		
		table += "<table id=\"table_" + tableCount + "\" cellspacing=\"0\" cellpadding=\"0\" class=\"jtable\">" + "\n";
		
		Iterator it = rows.iterator();
		
		int rowNumber = 0;
		
		while (it.hasNext()) {
			
			Row row = (Row) it.next();
			
			String[] fields = row.getFields();
			
			int passedRowNumber = rowNumber;
			
			if (getPrintFileRowNumbers())
				passedRowNumber = row.getNumber();

			table += "\t" + this.addTableRow(fields,passedRowNumber, rowNumber) + "\n";
			
			rowNumber++;
		}

		table += "</table>";
		
		tableCount++;
			
		return table;
	}
	
	
	/**
	 * Adds a row to a table
	 * 
	 * @param data
	 * @param passedRowNumber
	 * @param rowNumber
	 * */
	private String addTableRow(String[] data, int passedRowNumber,int rowNumber){
		
		String type = "even";
		
		if (rowNumber % 2 == 0)
			type = "odd";
		
		String tableRow = "<tr id=\"r"+ passedRowNumber + "\" class=\"" + type + "\">\n";
		
		if (getPrintRowNumbers())
			tableRow += "<td class=\"jtd num\">"+ passedRowNumber +"</td>";
		
		for (int i = 0; i < data.length; i++) {
			tableRow += "\t\t<td id=\"r" + passedRowNumber + "_c" + i +"\" class=\"jtd r" + passedRowNumber + " c" + i +"\">" + data[i] + "</td>\n";	
		}
		
		tableRow += "\t</tr>";
		
		return tableRow;
	}
	
	
	/* -------------------- Getters and Setters -------------------- */
	
	
	public String getPageTitle() {
		return pageTitle;
	}
	
	public void setPageTitle(String pageTitle) {
		this.pageTitle = pageTitle;
	}
	
	public String getContentBefore() {
		return contentBefore;
	}
	
	public void setContentBefore(String contentBefore) {
		this.contentBefore = contentBefore;
	}
	
	public String getContentAfter() {
		return contentAfter;
	}
	
	public void setContentAfter(String contentAfter) {
		this.contentAfter = contentAfter;
	}
	
	public boolean getPrintFileRowNumbers() {
		return printFileRowNumbers;
	}
	
	public void setPrintFileRowNumbers(boolean printFileRowNumbers) {
		this.printFileRowNumbers = printFileRowNumbers;
	}
	
	public boolean getPrintRowNumbers() {
		return printRowNumbers;
	}
	
	public void setPrintRowNumbers(boolean printRowNumbers) {
		this.printRowNumbers = printRowNumbers;
	}
	
	public boolean getPrintHeaders() {
		return printHeaders;
	}
	
	public void setPrintHeaders(boolean printHeaders) {
		this.printHeaders = printHeaders;
	}
	
	public String getCssFilePath() {
		return cssFilePath;
	}
	
	public void setCssFilePath(String cssFilePath) {
		this.cssFilePath = cssFilePath;
	}
}
